﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Algobox.JuicyLib.Apps.NewedgeDownloader
{
    public static class FileAssetValuation
    {
        const char SEPERATOR_ROW = '\n';
        const char SEPERATOR_COL = ',';
        const int MIN_IX = 22;
        const int IX_PORTFOLIO = 0;
        const int IX_SEDOL = 5;
        const int IX_ISIN = 6;
        const int IX_RIC = 7;
        const int IX_NAME = 8;
        const int IX_QUANTITY = 10;
        const int IX_PRICE = 11;
        const int IX_CCY = 21;
        const int IX_DATE = 22;


        public static bool ProcessData(string data, DateTime fileDate)
        {

            List<Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation> items = new List<Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation>();

            Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation item;
            Algobox.JuicyLib.SQL.LiquidView.InstrumentsStock stock;

            // remove strings in inverted commas from data completely
            string[] dataArray = data.Split('"');
            data = String.Empty;
            for (int i = 0; i < dataArray.Length; i++)
            {
                if (i % 2 == 0)
                    data += dataArray[i];
            }

            DateTime date;
            long quantity;
            decimal price;

            var query = from csvline in data.Split(SEPERATOR_ROW)
                        let csv = csvline.Split(SEPERATOR_COL)
                        where csv.Length >= MIN_IX
                        select new
                        {
                            Portfolio = csv[IX_PORTFOLIO],
                            Sedol = csv[IX_SEDOL],
                            ISIN = csv[IX_ISIN],
                            RIC = csv[IX_RIC],
                            Name = csv[IX_NAME],
                            Quantity = csv[IX_QUANTITY],
                            Price = csv[IX_PRICE],
                            Currency = csv[IX_CCY],
                            Date = csv[IX_DATE]
                        };
            
            var enumerableQuery = query.GetEnumerator();
            for (int i = 0; enumerableQuery.MoveNext(); i++)
            {
                if (i == 0)
                    continue;

                var row = enumerableQuery.Current;

                try
                {      

                    if (!Int64.TryParse(row.Quantity, out quantity))
                    {
                        JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "AssetValuation - Failed to parse quantity for record RIC({0}) Account({1}) Quantity({2}) Price({3}) Date({4})", row.RIC, row.Portfolio, row.Quantity, row.Price, row.Date);
                        Console.WriteLine("AssetValuation Can't parse quantity:  " + row.Quantity);
                        continue;
                    }
                    if (!Decimal.TryParse(row.Price, out price))
                    {
                        JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "AssetValuation - Failed to parse price for record RIC({0}) Account({1}) Quantity({2}) Price({3}) Date({4})", row.RIC, row.Portfolio, row.Quantity, row.Price, row.Date);
                        Console.WriteLine("AssetValuation Can't parse price:  " + row.Price);
                        continue;
                    }
                    //if (!DateTime.TryParse(csv[IX_DATE], out date))
                    if (!DateTime.TryParseExact(row.Date,
                            "dd/MM/yyyy",
                            System.Globalization.CultureInfo.InvariantCulture,
                            System.Globalization.DateTimeStyles.None,
                            out date))
                    {
                        if (!DateTime.TryParseExact(row.Date,
                           "dd-MM-yyyy",
                           System.Globalization.CultureInfo.InvariantCulture,
                           System.Globalization.DateTimeStyles.None,
                           out date))
                        {
                            JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "AssetValuation - Failed to parse date for record RIC({0}) Account({1}) Quantity({2}) Price({3}) Date({4})", row.RIC, row.Portfolio, row.Quantity, row.Price, row.Date);
                            Console.WriteLine("AssetValuation Can't parse date:  " + row.Date);
                            continue;
                        }
                    }

                    if (row.Currency == "GBP")
                        price = price / 100;

                    item = new Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation();
                    item.Portfolio = row.Portfolio;
                    item.Quantity = quantity;
                    item.ClosingPrice = price;
                    item.ValuationDate = date;
                }
                catch
                {
                    continue;
                }


                if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(row.RIC, out stock))
                {
                    string symbol;
                    if (row.RIC.Contains('.'))
                    {
                        symbol = row.RIC.Substring(0, row.RIC.IndexOf('.'));
                    }
                    else
                    {
                        symbol = row.RIC;
                    }

                    if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(row.Currency, row.ISIN, row.Sedol, null, out stock))
                    {
                        if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(row.Currency, row.ISIN, null, null, out stock))
                        {
                            if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(row.Currency, null, row.Sedol, symbol, out stock))
                            {
                                if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(row.Currency, null, null, symbol, out stock))
                                {
                                    if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryCreateInstrumentStock(row.RIC, row.Currency, row.ISIN, row.Sedol, row.Name, null, out stock))
                                    {
                                        JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "AssetValuation - Failed to find security for Currency({0}) ISIN({1}) Sedol({2}) RIC({3}) Symbol({4})", row.Currency, row.ISIN, row.Sedol, row.RIC, symbol);
                                        Console.WriteLine("Failed to find security for Currency({0}) ISIN({1}) Sedol({2}) RIC({3}) Symbol({4})", row.Currency, row.ISIN, row.Sedol, row.RIC, symbol);
                                        continue;
                                    }
                                    else
                                    {
#if !DEBUG
                                        JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, null, null, row.RIC, null, null);
#endif
                                    }
                                }
                                else
                                {
#if !DEBUG
                                    JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, row.ISIN, row.Sedol, row.RIC, null, null);
#endif
                                }
                            }
                            else
                            {
#if !DEBUG
                                JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, row.ISIN, null, row.RIC, null, null);
#endif
                            }
                        }
                        else
                        {
#if !DEBUG
                            JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, null, row.Sedol, row.RIC, null, null);
#endif
                        }
                    }
                    else
                    {
#if !DEBUG
                        JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, null, null, row.RIC, null, null);
#endif
                    }
                }
                else
                {
#if !DEBUG
                    JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, row.ISIN, row.Sedol, null, null, null);
#endif
                }

                Console.WriteLine("AssetValuation Adding: {0} {1} {2} {3} {4}", item.ValuationDate, item.Portfolio, stock.Reuters, item.Quantity, item.ClosingPrice);

                item.StockId = stock.StockId;
                items.Add(item);
            }
            

            // remove previous data if exists
            foreach (string portfolio in items.Select(a => a.Portfolio).Distinct())
            {
                JuicyLib.SQL.LiquidView.LiquidViewHelper.TryRemoveNewedgeAssetValuation(fileDate, portfolio);
            }

            if (items.Count > 0)
            {
                if (JuicyLib.SQL.LiquidView.LiquidViewHelper.TryImportNewedgeAssetValuation(items))
                {
                    Console.WriteLine("AssetValuation Imported {0} open positions", items.Count);
                    return true;
                }
                else
                {
                    Console.WriteLine("AssetValuation Failed to import {0} AssetValuations", items.Count);
                }
            }

            return false;
        }

        //public static bool ProcessAssetValuation(string data, DateTime fileDate)
        //{

        //    List<Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation> items = new List<Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation>();

        //    using (CsvReader csv = new CsvReader(new StringReader(data), true, SEPERATOR_COL, '"', '\0', '#', true))
        //    {
        //        Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation item;
        //        Algobox.JuicyLib.SQL.LiquidView.InstrumentsStock stock;

        //        string sedol, isin, ric, currency, name;
        //        DateTime date;
        //        long quantity;
        //        decimal price;


        //        csv.DefaultParseErrorAction = ParseErrorAction.AdvanceToNextLine;
        //        while (csv.ReadNextRecord())
        //        {
        //            try
        //            {
        //                var query = from csvline in data.Split('\n')
        //                            let csv = csvline.Split(SEPERATOR_COL)
        //                            where csv.Length >= COLUMNS
        //                            select new
        //                            {
        //                                Account = csv[IX_ACCOUNT],
        //                                Side = csv[IX_SIDE],
        //                                Symbol = csv[IX_SYMBOL],
        //                                Quantity = csv[IX_QUANTITY],
        //                                Price = csv[IX_PRICE],
        //                                Destination = csv[IX_DEST],
        //                                Time = csv[IX_TIME],
        //                                Cusip = csv[IX_CUSIP],
        //                                Flag = csv[IX_FLAG],
        //                                OrderId = csv[IX_ORDERID],
        //                                RecordId = csv[IX_RECORDID],
        //                                Counterparty = csv[IX_CPTY]
        //                            };


        //                sedol = csv[IX_SEDOL];
        //                isin = csv[IX_ISIN];
        //                ric = csv[IX_RIC];
        //                name = csv[IX_NAME];
        //                currency = csv[IX_CCY];

        //                if (!Int64.TryParse(csv[IX_QUANTITY], out quantity))
        //                {
        //                    JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "Failed to parse quantity for record RIC({0}) Account({1}) Quantity({2}) Price({3}) Date({4})", ric, csv[IX_PORTFOLIO], csv[IX_QUANTITY], csv[IX_PRICE], csv[IX_DATE]);
        //                    Console.WriteLine("Can't parse quantity:  " + csv[IX_QUANTITY]);
        //                    continue;
        //                }
        //                if (!Decimal.TryParse(csv[IX_PRICE], out price))
        //                {
        //                    JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "Failed to parse price for record RIC({0}) Account({1}) Quantity({2}) Price({3}) Date({4})", ric, csv[IX_PORTFOLIO], csv[IX_QUANTITY], csv[IX_PRICE], csv[IX_DATE]);
        //                    Console.WriteLine("Can't parse price:  " + csv[IX_PRICE]);
        //                    continue;
        //                }
        //                //if (!DateTime.TryParse(csv[IX_DATE], out date))
        //                if (!DateTime.TryParseExact(csv[IX_DATE],
        //                       "dd/MM/yyyy",
        //                       System.Globalization.CultureInfo.InvariantCulture,
        //                       System.Globalization.DateTimeStyles.None,
        //                       out date))
        //                {
        //                    JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "Failed to parse date for record RIC({0}) Account({1}) Quantity({2}) Price({3}) Date({4})", ric, csv[IX_PORTFOLIO], csv[IX_QUANTITY], csv[IX_PRICE], csv[IX_DATE]);
        //                    Console.WriteLine("Can't parse date:  " + csv[IX_DATE]);
        //                    continue;
        //                }

        //                if (currency == "GBP")
        //                    price = price / 100;

        //                item = new Algobox.JuicyLib.SQL.LiquidView.NewedgeAssetValuation();
        //                item.Portfolio = csv[IX_PORTFOLIO];
        //                item.Quantity = quantity;
        //                item.ClosingPrice = price;
        //                item.ValuationDate = date;
        //            }
        //            catch
        //            {
        //                continue;
        //            }


        //            if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(ric, out stock))
        //            {
        //                string symbol;
        //                if (ric.Contains('.'))
        //                {
        //                    symbol = ric.Substring(0, ric.IndexOf('.'));
        //                }
        //                else
        //                {
        //                    symbol = ric;
        //                }

        //                if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(currency, isin, sedol, null, out stock))
        //                {
        //                    if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(currency, isin, null, null, out stock))
        //                    {
        //                        if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(currency, null, sedol, symbol, out stock))
        //                        {
        //                            if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryGetInstrumentStock(currency, null, null, symbol, out stock))
        //                            {
        //                                if (!JuicyLib.SQL.LiquidView.LiquidViewHelper.TryCreateInstrumentStock(ric, currency, isin, sedol, name, null, out stock))
        //                                {
        //                                    JuicyLib.SQL.LiquidView.LiquidViewHelper.LogException("NewedgeDownloader", "Failed to find security for Currency({0}) ISIN({1}) Sedol({2}) RIC({3}) Symbol({4})", currency, isin, sedol, ric, symbol);
        //                                    Console.WriteLine("Failed to find security for Currency({0}) ISIN({1}) Sedol({2}) RIC({3}) Symbol({4})", currency, isin, sedol, ric, symbol);
        //                                    continue;
        //                                }
        //                                else
        //                                {
        //                                    JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, null, null, ric, null, null);
        //                                }
        //                            }
        //                            else
        //                            {
        //                                JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, isin, sedol, ric, null, null);
        //                            }
        //                        }
        //                        else
        //                        {
        //                            JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, isin, null, ric, null, null);
        //                        }
        //                    }
        //                    else
        //                    {
        //                        JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, null, sedol, ric, null, null);
        //                    }
        //                }
        //                else
        //                {
        //                    JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, null, null, ric, null, null);
        //                }
        //            }
        //            else
        //            {
        //                JuicyLib.SQL.LiquidView.LiquidViewHelper.UpdateInstrumentStock(stock, isin, sedol, null, null, null);
        //            }

        //            Console.WriteLine("Adding: {0} {1} {2} {3} {4}", item.ValuationDate, item.Portfolio, stock.Reuters, item.Quantity, item.ClosingPrice);

        //            item.StockId = stock.StockId;
        //            items.Add(item);
        //        }
        //    }

        //    // remove previous data if exists
        //    foreach (string portfolio in items.Select(a => a.Portfolio).Distinct())
        //    {
        //        JuicyLib.SQL.LiquidView.LiquidViewHelper.TryRemoveNewedgeAssetValuation(fileDate, portfolio);
        //    }

        //    if (items.Count > 0)
        //    {
        //        if (JuicyLib.SQL.LiquidView.LiquidViewHelper.TryImportNewedgeAssetValuation(items))
        //        {
        //            Console.WriteLine("Imported {0} open positions", items.Count);
        //            return true;
        //        }
        //        else
        //        {
        //            Console.WriteLine("Failed to import {0} AssetValuations", items.Count);
        //        }
        //    }

        //    return false;
        //}   



    }

}
